home *** CD-ROM | disk | FTP | other *** search
- %include "ntice.inc"
- %include "ntddk.inc"
-
- BITS 32
-
- PatchData istruc NTIcedumpHdr
- at NTIcedumpHdr.ID, db NTICEDUMP_ID ; speaks for itself
- at NTIcedumpHdr.Len, dw PATCH_HEADER_SIZE ; header size
- at NTIcedumpHdr.PatchVer, dw 0100h ; nticedump patcher version
- at NTIcedumpHdr.Ver, dd NTICEDUMP_BUILD ; nticedump version
- at NTIcedumpHdr.SiVer, dd NTICE_VERSION ; target SoftICE version
- at NTIcedumpHdr.VA, dd Init ; RVA of Call to Init
- iend
- ; insert any extra data here
- ; i.e. Credits string
- ; but keep below 64k =)
- db 'IceDump ',VERSION_TO_ASCII(NTICEDUMP_BUILD),' for NTICE ',VERSION_TO_ASCII(NTICE_VERSION),0
- .End:
-
- PATCH_HEADER_SIZE EQU (PatchData.End - PatchData)
- %assign PATCH_ORIGIN_ADJUSTED (PAGEIN_PATCH_ORIGIN - PATCH_HEADER_SIZE)
-
-
- ORG PATCH_ORIGIN_ADJUSTED
-
- ;-------------------------------------------------------------------------------
- ; Init will be called by NT. Takes 2 DWORDS as params. This call is
- ; responsible with the debug extension vector init, as well as "normal"
- ; NTICE initialization. It will replace original DriverEntry. The PE entry
- ; point will be set to point to this routine.
- ;-------------------------------------------------------------------------------
- Init:
- %if NTICE_VERSION = 0x322 || NTICE_VERSION = 0x323
-
- call .delta322
- .delta322:
- pop eax
- sub eax, .delta322
- lea ecx, [eax+Init]
- push ecx
- pop dword [eax+SELF_REF]
- %endif ; END 322 & 323 specific initialization patches
-
- push dword [esp+8] ; push pRegistryPath
- push dword [esp+8] ; push pDriverObject
- call pNticeInit ; call NticeDeviceInit
- test eax, eax ; EAX = STATUS_SUCCESS ?
- jl near .return ; nope, branch error
-
- pushad ; save'em all
-
- call .delta
- .delta:
- pop ebp ; EBP: Current Address
- sub ebp, .delta ;
-
- .fixups:
- mov ecx, MaxSrv ; initialize loop count
- lea edi, [ebp+tInternalApiTable] ; EDI: pointer to internal API table
-
- .next_service:
- add dword [edi], ebp ; perform fixup
- add edi, byte 4 ; advance to next slot
- loop .next_service ; more API's ?
-
- .get_ntoskrnl_ptrs:
- lea edi, [ebp+CallTable] ; EBX: pointer to Call Table
- lea esi, [ebp+tImportNameTable] ; ESI: pointer to API Names
- mov ecx, MaxImportId ; intialize loop count
-
- .next_api:
- call pExpression2Integer ; return EAX: API virtual address
- jb .exit ; Fail extension commands initialization on error
-
- stosd ; store API pointer in Call table
- inc esi ; step to next string
- loop .next_api
-
- .apply_patches:
- mov ebx, cr0 ; EBX: CR0
- push ebx ; save it for later use
- btr ebx, 16 ; Clear Write Protect bit
- mov cr0, ebx
-
- mov byte [ebp+CRS_END], 0xC3 ; patch retn
- mov byte [ebp+PAGEIN_CMDLINE], 0xBE ; patch mov esi, imm32
- mov dword [ebp+PAGEIN_PARSER+1], Parser - PAGEIN_PARSER - 5
- mov dword [ebp+PCI_VENDORS], -1
- lea eax, [ebp+Init]
- mov dword [ebp+dIGNOREFAULTS1], eax ; let ntoskrnl
- lea eax, [ebp+End] ; handle faults
- mov dword [ebp+dIGNOREFAULTS2], eax ; in this range
-
- ; hook pINT3_CleanupForPAGEIN
- lea eax,[ebp+pINT3_CleanupForPAGEIN+0x18] ; call pMemcopy
- lea ebx,[ebp+HookCleanupForPAGEIN-4]
- sub ebx,eax
- mov [eax],ebx
-
- pop ebx
- mov cr0, ebx ;revert CR0 to normal state
-
- .hook_idt:
- mov dl, 0x60 ; Interrupt Gate DPL = 3
- lea edi, [ebp+Icall_handler] ; handler EIP = Icall_handler
- mov eax, 0xFF ; target vector 0xFF
- call pHookInt_IDT ; Hook IDT
-
- .exit:
- popad ; restore all registers
-
- .return:
- retn 8 ; return to OS (__stdcall always assumed for DriverEntry )
-
-
- ;-------------------------------------------------------------------------------
- ;
- ;-------------------------------------------------------------------------------
-
- Parser:
- pushad
- call .delta
- .delta:
- pop ebp ;
- sub ebp, .delta
-
- call pSaveRegs ; save client State
- call pSkipWord ; skip over PAGEIN
- jb Parse_Help
-
- lodsb
- and al, 0x5F ; toupper
- cmp al, 'D'
- jz near Parse_Dump
-
- cmp al, 'S'
- jz Parse_Suspend
-
- cmp al, 'R'
- jz Parse_Resume
-
- cmp al, 'B'
- jz Parse_Bhrama
-
- cmp al, 'L'
- jz near Parse_Load
-
- jmp short Parse_Help
-
- .error:
- push ebx
- call pPrintErrorToCommandWindow
-
- .exit:
- call pRestoreRegs ; restore client state
- popad
- retn
-
- Parse_Help:
- lea ebx, [ebp+help_d]
- push ebx
- call pPrintErrorToCommandWindow
-
- lea ebx, [ebp+help_s]
- push ebx
- call pPrintErrorToCommandWindow
-
- lea ebx, [ebp+help_r]
- push ebx
- call pPrintErrorToCommandWindow
-
- lea ebx, [ebp+help_b]
- push ebx
- call pPrintErrorToCommandWindow
-
- lea ebx, [ebp+help_l]
- push ebx
- call pPrintErrorToCommandWindow
-
- lea ebx, [ebp+help_v]
- push ebx
- call pPrintErrorToCommandWindow
-
- jmp short Parser.exit
-
- Parse_Suspend:
- ; mov dword [ebp+dClient_EAX], Srv_Suspend
- lea ebx, [ebp+nim_err]
- jmp Parser.error
-
- Parse_Resume:
- ; mov dword [ebp+dClient_EAX], Srv_Resume
- lea ebx , [ebp+nim_err]
- jmp Parser.error
-
- Parse_Bhrama:
- lea ebx,[ebp+Error_V86]
- test byte [ebp+dClient_EFLAGS+2],2 ; is client in V86 mode?
- jnz near Parser.error
-
- lea ebx,[ebp+Error_PM16]
- lar eax,[ebp+dClient_CS] ; is client 32 bit?
- bt eax,22
- jnc near Parser.error
-
- lea ebx,[ebp+Error_PMR0]
- test byte [ebp+dClient_CS],3 ; is client in ring-0?
- jz near Parser.error
-
- lea ebx,[ebp+Error_NoWnd]
- call pSkipWhiteSpace
- jz near Parser.error
-
- call GetAPIs
- lea ebx,[ebp+Error_API]
- jc near Parser.error
-
- mov ebx,cr0
- push ebx
- btr ebx,16
- mov cr0,ebx
-
- mov eax,[ebp+dClient_EIP] ; use current EIP
- mov [ebp+Bhrama_Struc+BhramaComStruc.EIP],eax
-
- mov edi,esi
- mov ecx,-1
- xor eax,eax
- repnz scasb
- sub edi,esi
- mov ecx,edi
- lea edi,[ebp+Procdump.WindowName]
- rep movsb
- stosb
-
- lea esi,[ebp+Procdump]
- mov ecx,Bhrama_Struc.end-Procdump
- call CopyToUserLand
- or eax,eax
- jnz .1
-
- pop ebx
- mov cr0,ebx
- lea ebx,[ebp+Error_NoUser]
- jmp Parser.error
-
- .1:
- mov dword [ebp+dClient_EBP],eax
- mov dword [ebp+dClient_EIP],eax ; set client (E)IP
- mov dword [ebp+dClient_ESP],eax ; set client (E)SP
- sub dword [ebp+dClient_ESP],byte 4
- mov dword [ebp+oPAGEIN_INT3],eax ; set address of final INT3
- add dword [ebp+oPAGEIN_INT3],byte Procdump.return-Procdump
-
- mov ebx,[ebp+API.oGetCurrentProcessID]
- mov [eax+Procdump.oGetCurrentProcessID-Procdump-4],ebx
- sub [eax+Procdump.oGetCurrentProcessID-Procdump-4],eax
- sub dword [eax+Procdump.oGetCurrentProcessID-Procdump-4],byte Procdump.oGetCurrentProcessID-Procdump
-
- mov ebx,[ebp+API.oFindWindowA]
- mov [eax+Procdump.oFindWindowA-Procdump-4],ebx
- sub [eax+Procdump.oFindWindowA-Procdump-4],eax
- sub dword [eax+Procdump.oFindWindowA-Procdump-4],byte Procdump.oFindWindowA-Procdump
-
- mov ebx,[ebp+API.oSendMessageA]
- mov [eax+Procdump.oSendMessageA-Procdump-4],ebx
- sub [eax+Procdump.oSendMessageA-Procdump-4],eax
- sub dword [eax+Procdump.oSendMessageA-Procdump-4],byte Procdump.oSendMessageA-Procdump
-
- mov [eax+Procdump.DataPointer-Procdump],eax
- add dword [eax+Procdump.DataPointer-Procdump],byte Bhrama_Struc-Procdump
-
- lea eax,[eax+Procdump.WindowName-Procdump]
- mov [ebp+dClient_ESI],eax ; bhrama server's window name
-
- pop ebx
- mov cr0,ebx
-
- xor eax,eax
- inc eax
-
- mov [ebp+fPAGEIN_InProgress],eax ; set internal Winice flag to 1
- mov [ebp+fExecuteMoreCommands],ah ; set internal Winice flag to 0
-
- popad
- retn
-
-
- ; ------------------------------------------------------------------------------
- ; this is where we call Procdump based on Stone's example
- ;
- ; ebp: linear address of Procdump on client stack
- ; esi: Bhrama window name
- ; ------------------------------------------------------------------------------
- align 4
- Procdump:
- call .oGetCurrentProcessID
- .oGetCurrentProcessID:
-
- mov [ebp+Bhrama_Struc+BhramaComStruc.PID-Procdump],eax
- ; mov [Bhrama_Struc+BhramaComStruc.EIP],0x0
- ; mov [Bhrama_Struc+BhramaComStruc.OptL1],0x00000000
- ; mov [Bhrama_Struc+BhramaComStruc.OptL2],0x01000001
- ; mov [Bhrama_Struc+BhramaComStruc.OptL3],0x01010001
- ; mov [Bhrama_Struc+BhramaComStruc.OptL4],0x00010000
- ; mov [Bhrama_Struc+BhramaComStruc.OptL5],0x00000000
-
- ; LookUp for ProcDump Server.
- push esi
- push byte 0
- call .oFindWindowA
- .oFindWindowA:
-
- test eax,eax
- jz .return
-
- ; Send Dump Message to ProcDump Server.
- .sendmsg:
- add ebp,byte .Service-Procdump
- push ebp
- push byte 0
- push byte WM_COPYDATA
- push eax ; ProcDump's hwnd
- call .oSendMessageA
- .oSendMessageA:
-
- .return:
- int3
-
-
- align 4
- .WindowName: times 64 db 0
-
- align 4
- .Service: dd 1
- .DataLength: dd BhramaComStruc_size
- .DataPointer: dd Bhrama_Struc
-
- Bhrama_Struc:
- istruc BhramaComStruc
- at BhramaComStruc.version, dd 3
- at BhramaComStruc.PID, dd 0
- at BhramaComStruc.EIP, dd 0
- at BhramaComStruc.OptL1, dd 0x00000000
- at BhramaComStruc.OptL2, dd 0x01000101
- at BhramaComStruc.OptL3, dd 0x01010001
- at BhramaComStruc.OptL4, dd 0x00030000
- at BhramaComStruc.OptL5, dd 0x00000000
- iend
- .end:
-
-
- Parse_Dump:
- call pSkipWhiteSpace
- jz .set_pth_mode
-
- lea ebx, [ebp+evl_err]
- call pExpression2Integer ; Parse address
- jb near Parser.error
-
- mov [ebp+dClient_EDI], eax ; store address in Client_EDI
- mov dword [ebp+dClient_EAX], Srv_Dump ; srv code goes in EAX
- call pSkipWhiteSpace
- jz .emulate ; emulate old PAGEIN behaviour
-
- call pExpression2Integer ; Parse Length
- jb near Parser.error
-
- call pSkipWhiteSpace ; advance to filename
- jnz .cont ; ESI: pointer to file name
-
- jmp Parser.exit
-
- .set_pth_mode:
- xor byte [ebp+PathMode], 1
- lea ebx, [ebp+msg_p0]
- jnz .on
-
- lea ebx, [ebp+msg_p1]
- .on:
- jmp Parser.error
-
- .emulate:
- xor eax, eax ; Zero length
- xor esi, esi ; No file name
- jmp .exprt_mode
-
- .cont:
- cmp byte [ebp+PathMode], 1
- jz .exprt_mode
- sub esi, 4
- mov dword [esi], '\??\'
-
- .exprt_mode:
- mov [ebp+dClient_ESI], esi ; pointer to filename
- mov [ebp+dClient_ECX], eax ; store length
- call CanResume ; are we allowed to play the game ?
-
- test byte [ebp+dClient_CS], 3 ; ring-0 Client ?
- jz near .ring0
-
- mov ecx, EntryPoint.end - EntryPoint; number of bytes to copy
- push ecx
-
- lea eax, [ebp+EntryPoint] ; EAX: source
- push eax
-
- test byte [ebp+dClient_EFLAGS+2], 2 ; V86 mode client?
- jz .PM
-
- mov eax,cr4
- test eax,1 ; CR4.VME
- jz .set_iopl
-
- str ax
- call pMapSelectorToLinAddr
- jnc .set_redirection
-
- lea ebx, [ebp+tss_err]
- push ebx
- call pPrintErrorToCommandWindow
- jmp Parser.exit
-
- .set_redirection:
- movzx edi, word [eax+0x66] ; start of i/o perm map
- lea edi, [edi+eax-0x20] ; start of int redir map
- mov eax, 0xFF ; our interrupt
- bts [edi], eax ; no redirection to V86 handler
-
- .set_iopl:
- mov eax, [ebp+dClient_EFLAGS] ; save IOPL
- mov [ebp+dClient_EBX], eax
- or byte [ebp+dClient_EFLAGS+1], 0x30 ; IOPL=3
-
- movzx eax, word [ebp+dClient_SS]
- mov [ebp+dClient_CS], eax ; set new client CS
- shl eax, 4
- movzx edi, word [ebp+dClient_ESP]
- sub edi, ecx ; bug, should handle underflow
- add eax, edi
- push eax
- jmp short .copy
-
- .PM:
- movzx eax, word [ebp+dClient_SS]
- call pMapSelectorToLinAddr
- jnc .got_linaddr
-
- add esp, byte 8
- lea ebx, [ebp+sel_err]
- jmp Parser.error
-
- .got_linaddr:
- mov edi, eax
- add edi, [ebp+dClient_ESP] ; EDI: linear Client ESP
- sub edi, ecx ; EDI destination ( on client Stack )
- push edi
- mov word [ebp+dClient_CS], 0x1B ; set new client CS
- mov word [ebp+dClient_SS], 0x23 ; set new client SS
-
- .copy:
- call pMemcopy ; memcpy with protection from faults
- lea ebx, [ebp+stk_err]
- test eax, eax
- jz near Parser.error
-
- mov ebx, edi ; EBX: new EIP
- lea eax, [edi+EntryPoint.i3-EntryPoint]; EAX: INT3 location
- mov [ebp+dClient_ESP], edi ; adjust client stack
- jmp short .setup
-
- .ring0:
- lea eax, [ebp+EntryPoint.i3] ; INT3 location for ring-0 code
- lea ebx, [ebp+EntryPoint] ; Get EIP
-
- .setup:
- mov [ebp+oPAGEIN_INT3], eax ; register INT3 location
- mov [ebp+dClient_EIP], ebx ; set new client EIP
- xor eax, eax
- inc eax
- mov [ebp+fPAGEIN_InProgress], eax ; set PAGEIN internal var
- mov [ebp+fExecuteMoreCommands], ah ; leave ntice
- popad
- retn
-
- PathMode: db 1
-
-
- Parse_Load:
- call pSkipWhiteSpace
- jz .set_pth_mode
-
- lea ebx, [ebp+evl_err]
- call pExpression2Integer ; Parse address
- jb near Parser.error
-
- mov [ebp+dClient_EDI], eax ; store address in Client_EDI
- mov dword [ebp+dClient_EAX], Srv_Load ; srv code goes in EAX
- call pSkipWhiteSpace
- jz near Parser.error
-
- call pExpression2Integer ; Parse Length
- jb near Parser.error
-
- call pSkipWhiteSpace ; advance to filename
- jnz .cont ; ESI: pointer to file name
-
- jmp Parser.exit
-
- .set_pth_mode:
- xor byte [ebp+PathMode], 1
- lea ebx, [ebp+msg_p0]
- jnz .on
-
- lea ebx, [ebp+msg_p1]
- .on:
- jmp Parser.error
-
- .cont:
- cmp byte [ebp+PathMode], 1
- jz .exprt_mode
-
- sub esi, 4
- mov dword [esi], '\??\'
-
- .exprt_mode:
- mov [ebp+dClient_ESI], esi ; pointer to filename
- mov [ebp+dClient_ECX], eax ; store length
- call CanResume ; are we allowed to play the game ?
-
- test byte [ebp+dClient_CS], 3 ; ring-0 Client ?
- jz near .ring0
-
- mov ecx, EntryPoint.end - EntryPoint; number of bytes to copy
- push ecx
-
- lea eax, [ebp+EntryPoint] ; EAX: source
- push eax
-
- test byte [ebp+dClient_EFLAGS+2], 2 ; V86 mode client?
- jz .PM
-
- mov eax,cr4
- test eax,1 ; CR4.VME
- jz .set_iopl
-
- str ax
- call pMapSelectorToLinAddr
- jnc .set_redirection
-
- lea ebx, [ebp+tss_err]
- push ebx
- call pPrintErrorToCommandWindow
- jmp Parser.exit
-
- .set_redirection:
- movzx edi, word [eax+0x66] ; start of i/o perm map
- lea edi, [edi+eax-0x20] ; start of int redir map
- mov eax, 0xFF ; our interrupt
- bts [edi], eax ; no redirection to V86 handler
-
- .set_iopl:
- mov eax, [ebp+dClient_EFLAGS] ; save IOPL
- mov [ebp+dClient_EBX], eax
- or byte [ebp+dClient_EFLAGS+1], 0x30 ; IOPL=3
-
- movzx eax, word [ebp+dClient_SS]
- mov [ebp+dClient_CS], eax ; set new client CS
- shl eax, 4
- movzx edi, word [ebp+dClient_ESP]
- sub edi, ecx ; bug, should handle underflow
- add eax, edi
- push eax
- jmp short .copy
-
- .PM:
- movzx eax, word [ebp+dClient_SS]
- call pMapSelectorToLinAddr
- jnc .got_linaddr
-
- add esp, byte 8
- lea ebx, [ebp+sel_err]
- jmp Parser.error
-
- .got_linaddr:
- mov edi, eax
- add edi, [ebp+dClient_ESP] ; EDI: linear Client ESP
- sub edi, ecx ; EDI destination ( on client Stack )
- push edi
- mov word [ebp+dClient_CS], 0x1B ; set new client CS
- mov word [ebp+dClient_SS], 0x23 ; set new client SS
-
- .copy:
- call pMemcopy ; memcpy with protection from faults
- lea ebx, [ebp+stk_err]
- test eax, eax
- jz near Parser.error
-
- mov ebx, edi ; EBX: new EIP
- lea eax, [edi+EntryPoint.i3-EntryPoint]; EAX: INT3 location
- mov [ebp+dClient_ESP], edi ; adjust client stack
- jmp short .setup
-
- .ring0:
- lea eax, [ebp+EntryPoint.i3] ; INT3 location for ring-0 code
- lea ebx, [ebp+EntryPoint] ; Get EIP
-
- .setup:
- mov [ebp+oPAGEIN_INT3], eax ; register INT3 location
- mov [ebp+dClient_EIP], ebx ; set new client EIP
- xor eax, eax
- inc eax
- mov [ebp+fPAGEIN_InProgress], eax ; set PAGEIN internal var
- mov [ebp+fExecuteMoreCommands], ah ; leave ntice
- popad
- retn
-
-
- ;-------------------------------------------------------------------------------
- ; Check if we are allowed to tweak client execution. In case of error, it
- ; will NOT return to the caller.
- ;-------------------------------------------------------------------------------
- CanResume:
- call pGetIRQLLevel ; Get current IRQL level
- lea ebx, [ebp+irq_err]
- cmp eax, byte 2 ; IRQL > Dispatch_Level ?
- jnb .error
-
- lea ebx, [ebp+int_err]
- test byte [ebp+dClient_EFLAGS+1], 2 ; interrupts enabled
- jz .error ; nope, bye
-
- lea ebx, [ebp+ctx_err]
- mov eax, [ebp+dCurrentContext]
- cmp eax, [ebp+dPopupContext]
- jnz .error
-
- retn
-
- .error:
- pop eax ; Remove return address from stack
- jmp Parser.error ; and branch command parser exit
- ; That's it, return to NTICE,
- ; nothing to be done
-
-
- ;------------------------------------------------------------------------------------
- ; client EAX: service ID
- ; client EBX: EFLAGS having original IOPL, only for V86 mode
- ;
- ; rest is service dependent
- ;------------------------------------------------------------------------------------
- EntryPoint:
- int 0xFF ; Initiate an extension call
- .i3:
- int3 ; Break back in NTICE
- .end:
-
- Icall_handler:
- ExceptionFrame2KeTrapFrame HW_ERROR_CODE_OFF, PRIMARY
- call .delta
- .delta:
- pop esi
- sub esi, .delta
-
- test byte [ebp+KeTrapFrame.EFLAGS+2], 2 ; EFLAGS.VM
- jz .PM
-
- mov eax, [ebp+KeTrapFrame.EBX] ; grab EFLAGS
- mov [ebp+KeTrapFrame.EFLAGS], eax ; restore IOPL
-
- .PM:
- mov eax, [ebp+KeTrapFrame.EAX] ; grab service ID
- mov [ebp+KeTrapFrame.EAX], esi ; Save ntice base in the trap frame
- add esi, tInternalApiTable ; ESI: ptr to extension routines table
- sti
- call [esi+eax*4] ; call requested service
- cli
- KeTrapFrame2ExceptionFrame HW_ERROR_CODE_ON, PRIMARY
- iretd
-
-
- ;-------------------------------------------------------------------------------
- SrvVer:
- retn
-
- ;-------------------------------------------------------------------------------
- SrvDump:
- mov eax, ebp ; EAX : trape frame ptr
- push ebp ; save trape frame ptr
- sub esp, 8+8+24+8+4
- mov ebp, esp
- mov esi, [eax+KeTrapFrame.EAX] ;
- lea edi, [esi+CallTable] ; EDI: ntoskrnl import table
- cmp dword [eax+KeTrapFrame.ESI], byte 0 ; Do we have a filename ptr ?
- jz near .emulate ; If no , emulate old PAGEIN
- ; [ebp+52] == Trap frame ptr
- ; [ebp+48] == FileHandle
- ; EBP+40 == IoStatusBlock
- ; EBP+16 == Object Attributes
- ; EBP+8 == AnsiString
- ; EBP == UnicodeString
-
- lea eax, [ebp+16] ; get ptr to Object Attributes
- InitializeObjectAttributes ebp , dword 0x40 , dword 0 , dword 0
- mov eax, [ebp+52] ; EAX: ptr Trap frame
- push dword [eax+KeTrapFrame.ESI]
- lea eax, [ebp+8] ; OUT PANSI_STRING
- push eax
- call [edi+RtlInitAnsiString]
-
- push byte 1 ; Allocate Destination String Buffer
- lea eax, [ebp+8] ; IN PANSI_STRING
- push eax
- push ebp ; OUT PUNICODE_STRING
- call [edi+RtlAnsiStringToUnicodeString]
-
- push byte 0
- push byte 0
- push dword 0x850
- push byte 5 ; FILE_SUPERSEED
- push byte 0 ; no sharing
- push dword 0x80 ; FILE_ATTRIBUTE_NORMAL
- push byte 0 ; allocation size 0
- lea eax, [ebp+40] ; EAX: PIO_STATUS_BLOCK
- push eax
- lea eax, [ebp+16] ; EAX: POBJECT_ATTRIBUTES
- push eax
- push dword 0x120116 ; Desired Access
- lea eax, [ebp+48] ; ptr File Handle
- push eax
- lea ebx, [esi+opn_err]
- call [edi+ZwCreateFile]
- test eax, eax
- jl .free_string
-
- push byte 0 ; No KEY
- push byte 0 ; Null File Offset
- mov eax, [ebp+52]
- push dword [eax+KeTrapFrame.ECX] ; Length
- push dword [eax+KeTrapFrame.EDI] ; buffer address
- lea eax, [ebp+40] ; PIO_STATUS_BLOCK
- push eax
- push byte 0 ; null APC context
- push byte 0 ; no APC
- push byte 0 ; no completion Event
- push dword [ebp+48] ; File handle
- lea ebx, [esi+wrt_err]
- call [edi+ZwWriteFile]
- test eax, eax
- jl .free_close
-
- push ebp
- call [edi+RtlFreeUnicodeString] ; Free temp unicode storage space
-
- push dword [ebp+48]
- call [edi+ZwClose] ; Close the file
- jmp short .return
-
- .emulate:
- lea ebx, [esi+npr_err]
- mov esi, [ebp+52] ; ESI = ptr trap frame
- mov esi, [esi+KeTrapFrame.EDI] ; ESI: pagein address
- push esi
- call [edi+MmIsAddressValid] ; check if it is a valid address
- test al, al
- jz .error
-
- mov eax, [esi] ; touch the page and bring it in
-
- .return:
- add esp, 8+8+24+8+4
- pop ebp
- retn ; return to Icall_Handler
-
- .free_close:
- push dword [ebp+48]
- call [edi+ZwClose]
-
- .free_string:
- push ebp
- call [edi+RtlFreeUnicodeString]
-
- .error:
- push ebx ; EBX: ptr to error msg
- call [edi+DbgPrint] ; print error msg
- pop eax ; DbgPrint follows C calling convention
- jmp short .return
-
-
- ;-------------------------------------------------------------------------------
- SrvDumpX:
- retn
-
-
- ;-------------------------------------------------------------------------------
- SrvSr:
- retn
-
-
- ;-------------------------------------------------------------------------------
- SrvBhr:
- retn
-
-
- ;-------------------------------------------------------------------------------
- SrvLoad:
- mov eax, ebp ; EAX : trape frame ptr
- push ebp ; save trape frame ptr
- sub esp, 8+8+24+8+4
- mov ebp, esp
- mov esi, [eax+KeTrapFrame.EAX]
- lea edi, [esi+CallTable] ; EDI: ntoskrnl import table
-
- ; [ebp+52] == Trap frame ptr
- ; [ebp+48] == FileHandle
- ; EBP+40 == IoStatusBlock
- ; EBP+16 == Object Attributes
- ; EBP+8 == AnsiString
- ; EBP == UnicodeString
-
- lea eax, [ebp+16] ; get ptr to Object Attributes
- InitializeObjectAttributes ebp , dword 0x40 , dword 0 , dword 0
- mov eax, [ebp+52] ; EAX: ptr Trap frame
- push dword [eax+KeTrapFrame.ESI]
- lea eax, [ebp+8] ; OUT PANSI_STRING
- push eax
- call [edi+RtlInitAnsiString]
-
- push byte 1 ; Allocate Destination String Buffer
- lea eax, [ebp+8] ; IN PANSI_STRING
- push eax
- push ebp ; OUT PUNICODE_STRING
- call [edi+RtlAnsiStringToUnicodeString]
-
- push byte 0
- push byte 0
- push dword 0x850
- push byte 1 ; FILE_OPEN
- push byte 1 ; share: read
- push byte 0 ; attribs don't apply
- push byte 0 ; allocation size 0
- lea eax, [ebp+40] ; EAX: PIO_STATUS_BLOCK
- push eax
- lea eax, [ebp+16] ; EAX: POBJECT_ATTRIBUTES
- push eax
- push dword 0x120109 ; Desired Access
- lea eax, [ebp+48] ; ptr File Handle
- push eax
- lea ebx, [esi+opn_err]
- call [edi+ZwCreateFile]
- test eax, eax
- jl .free_string
-
- push byte 0 ; No KEY
- push byte 0 ; Null File Offset
- mov eax, [ebp+52]
- push dword [eax+KeTrapFrame.ECX] ; Length
- push dword [eax+KeTrapFrame.EDI] ; buffer address
- lea eax, [ebp+40] ; PIO_STATUS_BLOCK
- push eax
- push byte 0 ; null APC context
- push byte 0 ; no APC
- push byte 0 ; no completion Event
- push dword [ebp+48] ; File handle
- lea ebx, [esi+wrt_err]
- call [edi+ZwReadFile]
- test eax, eax
- jl .free_close
-
- push ebp
- call [edi+RtlFreeUnicodeString] ; Free temp unicode storage space
-
- push dword [ebp+48]
- call [edi+ZwClose] ; Close the file
-
- .return:
- add esp, 8+8+24+8+4
- pop ebp
- retn ; return to Icall_Handler
-
- .free_close:
- push dword [ebp+48]
- call [edi+ZwClose]
-
- .free_string:
- push ebp
- call [edi+RtlFreeUnicodeString]
-
- .error:
- push ebx ; EBX: ptr to error msg
- call [edi+DbgPrint] ; print error msg
- pop eax ; DbgPrint follows C calling convention
- jmp short .return
-
-
- ;------------------------------------------------------------------------------
- ; The following call will be assembled only if target NTICE version is 322,
- ; which does not have a pGetIrqlLevel in the form we expect. This call can be
- ; guaranteed as safe only in NT 4.0, since it relies on the hardcoded value of
- ; KPCR base
-
- %if NTICE_VERSION = 0x322
-
- pGetIRQLLevel:
- push edi
- mov edi, KPCRSelfPointer+KPCR.Irql
- call pMOV_AL_EDI_safe
- pop edi
- jc .error
-
- movzx eax, al
- retn
-
- .error:
- mov eax, 3
- retn
- %endif
-
-
- ;-------------------------------------------------------------------------------
- ; ecx: amount, esi: dataptr, ebp: ntice base
- ;
- ; eax: destination or 0 on error
- ;-------------------------------------------------------------------------------
- CopyToUserLand:
- xor eax,eax
-
- cmp dword [ebp+UserLandBuffer.size],byte 0
- jz .1
-
- retn
-
- .1:
- cmp ecx,SAVEBUFFERSIZE
- jb .2
-
- retn
-
- .2:
- push edi
- mov edi,[ebp+dClient_ESP]
- and edi,0xFFFFF000
-
- call pMOV_AL_EDI_safe ; is page present?
- jnc .3
-
- xor eax,eax
- pop edi
- retn
-
- .3:
- mov [ebp+UserLandBuffer.size],ecx
- mov [ebp+UserLandBuffer.userptr],edi
- mov eax,edi ; save 'cos we will return it
-
- push ecx
- push esi
-
- mov esi,edi ; save user stack to temporary buffer
- lea edi,[ebp+UserLandBuffer.data]
- rep movsb
-
- pop esi ; copy data to the user stack
- pop ecx
- mov edi,eax
- rep movsb
-
- pop edi
- retn
-
-
- ;-------------------------------------------------------------------------------
- ; ebp: ntice base
- ;-------------------------------------------------------------------------------
- RestoreUserLand:
- cmp dword [ebp+UserLandBuffer.size],byte 0
- jnz .1
-
- retn
-
- .1:
- push ecx
- push esi
- push edi
- pushfd
- cld
-
- mov edi,[ebp+UserLandBuffer.userptr]
- lea esi,[ebp+UserLandBuffer.data] ; copy data to the user stack
- mov ecx,[ebp+UserLandBuffer.size]
- rep movsb
-
- mov dword [ebp+UserLandBuffer.size],0
- mov dword [ebp+UserLandBuffer.userptr],0
-
- popfd
- pop edi
- pop esi
- pop ecx
- retn
-
-
- ; save buffer, should be smaller than 4k (x86 page size)
- SAVEBUFFERSIZE equ 512
- align 4
- UserLandBuffer:
- .data: times SAVEBUFFERSIZE db 0
- .size: dd 0
- .userptr: dd 0
-
-
- ;-------------------------------------------------------------------------------
- ; call RestoreUserLand while cleanup after a PAGEIN like int3
- ;-------------------------------------------------------------------------------
- HookCleanupForPAGEIN:
- push ebp
- call .delta
- .delta:
- pop ebp
- sub ebp,.delta
- call RestoreUserLand
- pop ebp
- jmp pMemcopy
-
-
- ;-------------------------------------------------------------------------------
- ; resolve win32 api symbols
- ;-------------------------------------------------------------------------------
- GetAPIs:
- push esi
- push ecx
- push ebx
- push eax
-
- or ecx,byte -1
-
- mov ebx,cr0
- push ebx
- btr ebx,16
- mov cr0,ebx
-
- .loop:
- inc ecx
- cmp dword [8*ecx+ebp+API+4],byte 0
- jnz .1
-
- pop ebx
- mov cr0,ebx
-
- pop eax
- pop ebx
- pop ecx
- pop esi
-
- clc
- retn
-
- .1:
- cmp dword [8*ecx+ebp+API],byte 0
- jnz .loop
-
- mov esi,[8*ecx+ebp+API+4]
- add esi,ebp
-
- call pExpression2Integer
- jnb .2
-
- pop ebx
- mov cr0,ebx
-
- pop eax
- pop ebx
- pop ecx
- pop esi
-
- stc
- retn
-
- .2:
- mov [8*ecx+ebp+API],eax
- jmp short .loop
-
-
- align 4
-
- API:
- .oGetCurrentProcessID: dd 0, .GetCurrentProcessID
- .oFindWindowA: dd 0, .FindWindowA
- .oSendMessageA: dd 0, .SendMessageA
- ;.oOpenProcess: dd 0, .OpenProcess
- ;.oResumeThread: dd 0, .ResumeThread
- ;.oSuspendThread: dd 0, .SuspendThread
- ;.oExitThread: dd 0, .ExitThread
- ;.oExitProcess: dd 0, .ExitProcess
- ;.oTerminateThread: dd 0, .TerminateThread
- ;.oTerminateProcess: dd 0, .TerminateProcess
-
- ; null record, do not remove
- dd 0, 0
-
- .GetCurrentProcessID: db 'GetCurrentProcessID',0
- .FindWindowA: db 'FindWindowA',0
- .SendMessageA: db 'SendMessageA',0
- ;.OpenProcess: db 'OpenProcess',0
- ;.ResumeThread: db 'ResumeThread',0
- ;.SuspendThread: db 'SuspendThread',0
- ;.ExitThread: db 'ExitThread',0
- ;.ExitProcess: db 'ExitProcess',0
- ;.TerminateThread: db 'TerminateThread',0
- ;.TerminateProcess: db 'TerminateProcess',0
-
-
- tImportNameTable:
- db 'ZwCreateFile',0
- db 'ZwReadFile',0
- db 'ZwWriteFile',0
- db 'ZwClose',0
- db 'RtlAnsiStringToUnicodeString',0
- db 'RtlInitAnsiString',0
- db 'DbgPrint',0
- db 'RtlFreeUnicodeString',0
- db 'MmIsAddressValid',0
- db 'ZwSetInformationFile',0
- db 'KeAttachProcess',0
- db 'KeDetachProcess',0
- db 'KeInitializeDpc',0
- db 'KeInsertQueueDpc',0
-
- tKernel32NameTable:
-
-
- align 4
- CallTable: TIMES MaxImportId db 'SRVC'
-
- tInternalApiTable:
- dd SrvVer ;0 - version
- dd SrvDump ;1 - dump
- dd SrvSr ;2 - suspend
- dd SrvSr ;3 - resume
- dd SrvBhr ;4 - bhrama
- dd SrvDumpX ;5 - extended dump
- dd SrvLoad ;6 - load
-
-
- ;-------------------------------------------------------------------------------
- ; flag variables
- ;-------------------------------------------------------------------------------
-
-
-
- ;-------------------------------------------------------------------------------
- ; Error strings
- ;-------------------------------------------------------------------------------
- int_err db 'Interrupts must be enabled to use this extension.',0
- irq_err db 'IRQL must be below DISPATCH_LEVEL to use this extension.',0
- stk_err db 'Cannot use this extension because current thread`s stack is not present.',0
- tss_err db 'Unable to determine TSS base',0
- sel_err db 'Client SS is invalid???',0
- ctx_err db 'Cannot dump from this context. Revert to pop-up context.',0
- arg_err db 'Arguments required.',0
- evl_err db 'Cannot evaluate expression.',0
- prc_err db 'Cannot attach an invalid process. Check KPEB parameter.',0
- opn_err db 'Failed to create output file. Possible reason: wrong path name.',CRLF_0
- wrt_err db 'Failed to dump requested data. Possible reason: invalid memory range.',CRLF_0
- npr_err db 'Page at specified address is either Reserved or Not Committed.',CRLF_0
- msg_p0 db 'Path Expert mode is now on',0
- msg_p1 db 'Path Expert mode is now off',0
- nim_err db 'Command currently not implemented.',0
-
- Error_V86: db 'EFLAGS.VM=1, only win32 clients are supported.',0
- Error_PM16: db 'CS.D=0, only win32 clients are supported.',0
- Error_PMR0: db 'CS.DPL=0, only win32 clients are supported.',0
- Error_API: db 'unable to resolve some win32 APIs, check winice.dat.',0
- Error_NoID: db 'specify PID/TID.',0
- Error_NoWnd: db 'specify Bhrama server window name',0
- Error_NoUser: db 'could not copy to user land',0
-
- ;-------------------------------------------------------------------------------
- ; Help strings
- ;-------------------------------------------------------------------------------
- help_d db 'PAGEIN D <address> [ <length> <filename> ]',0
- help_d1 db 'PAGEIN D',0
- help_s db 'PAGEIN S <KTEB>',0
- help_r db 'PAGEIN R <KTEB>',0
- help_b db 'PAGEIN B <Bhrama window name>',0
- help_l db 'PAGEIN L <address> <length> <filename>',0
- help_v db 'nticedump Beta 1 build 0009 http://icedump.tsx.org.',0
-
- End:
-